# ----------------------------------------------------------------------------------------------
# load some helper functions
# - visualizing
#   - 
# - simple helper functions
source("commonmethods.R")


#----------------------------------------------------------------------------------------------
# load datasets and referencepartitions
# - 'samples' is a list containing samples
# - a sample has a field 'd' with dataset and a field 'rp' with referencepartion
#   and a field 'name' with the name of the dataset
# - a dataset is a two or three dimensional matrix with n datapoints as rows 
#   and X,Y xor X,Y,Z coordinates as columns
# - a referencepartition is a vector of clusternumbers with a length of n, 
#   each datapoint at row i of dataset 'd' is a clusternumber at position i 
#   in this vector assigned
source("samples.R")

#----------------------------------------------------------------------------------------------
# load indices with normalizing function
source("indices.R")

#----------------------------------------------------------------------------------------------
# load cluster methods with parameter generators
source("algos-and-paramgens.R")

			  	
#----------------------------------------------------------------------------------------------
analyseDataSet<-function(X,RP=NULL,datasetName,algos,indices,doG2G3=FALSE) {
	cat( paste("analysing dataset:", datasetName, "with"
	   , summary(X)," referenz:", summary(X), "with algos:", map(algos,"name"),"\n"));
	distX <- dist(X)
	statsPerAlgo <- list();
	for(algo in algos ) {
		#print(algo)
		# caluculate params
		params <- do.call(algo$params,list(distX,nrow(X)))
		# calculate partitions
		partitions <- runAlgoWithParams( X, distX, algo$name, params )
		
		statsPerParams<-list();i=1;
		
		## TODO : switch indexname <-> param pos
		for( p in partitions ) {
			stats<-cluster.stats(distX,p,RP,G2=doG2G3,G3=doG2G3)

			# Indices: normalize and handle unnormal values
			indexValues <- list()
			for( indexName in names(indices) ) {
				# read current indexValue from stats, using cluster.stats naming
				indexValue <- stats[[ indices[[indexName]]$name ]]
				indicesTransformation <- indices[[indexName]]$transf
				# apply index standard transformation, if given
				if( ! is.null(indicesTransformation) ) {
					indexValue<-do.call(indicesTransformation, list( indexValue ) )
				}
				
				# Map non existing Values to 0
				if(any( ! (length(indexValue) == 1)  
					, ! ( is.double(indexValue) || is.integer(indexValue) )
					, is.na(c(indexValue)) 
					, is.nan(c(indexValue))
					, is.infinite(indexValue)
					, is.null(indexValue))) { 
					indexValue=0
				}
				indexValues[[indexName]] = indexValue

			}
			statsPerParams[[i]]<-indexValues
			i=i+1;
		}
		# reorder from [(param1,[index1:value,index2:value..])] 
		# to algoname$indices$[(index1,[param1:value,param2:value ...])]
		for( indexName in c(names(indices)) ) {
			statsPerAlgo[[algo$name]][["indices"]][[indexName]] = 
				map(statsPerParams,indexName)
		}
		statsPerAlgo[[algo$name]]$params=params
		statsPerAlgo[[algo$name]]$partitions=partitions
	}
	statsPerAlgo$datasetName=datasetName
	statsPerAlgo$dataset$d=X
	statsPerAlgo$dataset$rp=RP
	statsPerAlgo;
}



#----------------------------------------------------------------------------------------------
# Configuration of Graphs

# symbol-Chars
chrs=	c(3:4 #,21 -> iim
		 ,22:25)
# colors
cols=   c("black","darkblue" #, "darkgreen" -> iim
        ,"darkorange4", "darkred" 
		, "darkmagenta", "darkviolet","darkgrey") 

# point size
cex = 1.0

# linewidth for rand index
lwd = 1.6 

#----------------------------------------------------------------------------------------------
plotSummary<-function(ads,algoName,main="Indexgraphen",ylab="Indices",ignoreidxs=c()) {
	params=ads[[algoName]]$params
	# plot all indices in one chart
	plot(y=c(),x=c(),xlim=c(1,length(params)),ylim=c(0,1),ylab=ylab,xlab="Parameterindex",main=main,			, cex.axis=1.1)
	c=1
	for(idx in names(ads[[algoName]]$indices) ) { 
		if( idx != "ClusterCount") { 
			if( ! ( idx %in% ignoreidxs ) ) { 
			values=ads[[algoName]]$indices[[idx]]
			stopifnot(values!=NULL)
			lines(values,type="b", pch=markMax(values,max=8,normalChar=chrs[c])
				 ,col=cols[c]
				 ,lty=c
				 , cex.axis=1.1
				 , cex=cex
				 , lwd = if( idx == "rand" ) lwd else 1.0 
				 );  
			}
			c=c+1
		}
	}
	abline(v=c(which.max(ads[[algoName]]$indices$rand)),lty=2,col="darkgray")
}

plotSummaryAndData<-function(ads,algoName) {
	plot(ads$dataset$d,col=cols[ads$dataset$rp],pch=chrs[ads$dataset$rp])
} 


plotAllIndices<-function(ads,algoName) {
 
	# Split plot in two columns
	algo<-algoName 
	stopifnot( ! ads==NULL , ! algo == NULL)

	par(mfrow=c(length(ads[[algo]]$indices)/2+1,2),cex.lab=1.2); 
	c=1;
	for( index in names(ads[[algo]]$indices) ) { 
		if( ! index == "ClusterCount") { 
		values=ads[[algo]]$indices[[index]]
		params=ads[[algo]]$params
		plot(values,pch=markMax(values,max=8,normalChar=chrs[c])
			, ylim=c(0,1)
			, main=paste("Index:",index,"max.:",round(max(values),2)
						,"@Param[",which.max(values),"] =",round(params[which.max(values)],2))
			, type="b", xlab="Parameterindex"
			, ylab=paste("Std. Index:",index),oma=par()$oma + c(1,1,1,1)
			, mar = c(5, 4, 4, 2) + 0.1
 		    , lty=c
			, col=cols[c]
			, cex.axis=1.1
			, cex=cex
			, lwd = if( index == "rand" ) lwd else 1.0 # highlight rand index
			) 
			c=c+1
		}
		abline(v=c(which.max(ads[[algo]]$indices$rand)),lty=2,col="darkgray")
	}


	plotSummary(ads,algoName)

	# handle Cluster Count spez.
	index="ClusterCount"
	values=ads[[algo]]$indices[[index]]
	params=ads[[algo]]$params
	plot(values,pch=11 
			, main=paste("Clusteranzahl")
			, type="b", xlab="Parameterindex"
			, ylab=paste("Clusteranzahl"),oma=par()$oma + c(1,1,1,1)
			, mar = c(5, 4, 4, 2) + 0.1
			, cex=cex
			, cex.axis=1.1
			) 	
			
	# plot parametervalues
	plot( ads[[algo]]$params, main="Parameter",type="b",xlab="Parameterindex"
	    , ylab="Parameterwert",oma=par()$oma + c(1,1,1,1)
		, mar = c(5, 4, 4, 2) + 0.1, cex=cex
		, cex.axis=1.1)
					
	# Set Main Title
	par(mfrow=c(1,1), oma=c(0,0,2,0)) ; 
	mtext(text=paste("Algo:",algo,"Dataset:",ads$datasetName),3
		 ,outer=T,cex = par("cex.main"))

}
